package site.jlopen.kuscia.service.datasource;

import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource.CreateDomainDataSourceResponse;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource.CreateDomainDataSourceResponseData;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource.DeleteDomainDataSourceResponse;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource.DomainDataSource;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource.ListDomainDataSourceRequest;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource.ListDomainDataSourceResponse;
import org.secretflow.v1alpha1.kusciaapi.Domaindatasource.QueryDomainDataSourceResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.protobuf.Descriptors;

import site.jlopen.kuscia.entity.GrpcApiInfo;
import site.jlopen.kuscia.enums.DataSourceTypeEnum;
import site.jlopen.kuscia.model.dataSource.KusciaDataSourceInfo;
import site.jlopen.kuscia.model.dataSource.KusciaOssDataSourceInfo;
import site.jlopen.kuscia.properties.KusciaAPIProperties;
import site.jlopen.kuscia.rpc.impl.KusciaDomainDataSourceRpcImpl;
import site.jlopen.kuscia.util.UUIDUtils;

@Service
public class KusciaDataSourceManager extends AbstractDataSourceManager {
	private static Logger logger = LoggerFactory.getLogger(KusciaDataSourceManager.class);

	@Override
	public String createDatasource(GrpcApiInfo apiInfo, String domainId, String dataSourceName,  KusciaOssDataSourceInfo sourceInfo) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		Domaindatasource.OssDataSourceInfo.Builder builder = Domaindatasource.OssDataSourceInfo.newBuilder()
                .setEndpoint(sourceInfo.getEndpoint())
                .setBucket(sourceInfo.getBucket())
                .setAccessKeyId(sourceInfo.getAccessKeyId())
                .setAccessKeySecret(sourceInfo.getAccessKeySecret());
		if (StringUtils.isNotBlank(sourceInfo.getPrefix())) {
            builder.setPrefix(sourceInfo.getPrefix());
        }
        if (StringUtils.isNotBlank(sourceInfo.getVirtualhost())) {
            builder.setVirtualhost(true);
        }
        String _datasourceId = "ds-id-" + UUIDUtils.random(8);
        Domaindatasource.CreateDomainDataSourceRequest request = Domaindatasource.CreateDomainDataSourceRequest.newBuilder()
                .setDomainId(domainId)
                .setType(DataSourceTypeEnum.OSS.name().toLowerCase(Locale.ROOT))
                .setName(dataSourceName)
                .setDatasourceId(_datasourceId)
                .setAccessDirectly(true)
                .setInfo(Domaindatasource.DataSourceInfo.newBuilder()
                        .setOss(builder.build())).build();
        CreateDomainDataSourceResponse response = new KusciaDomainDataSourceRpcImpl(apiProperties).createDomainDataSource(request);
        if(null == response) {
        	return null;
        }
        CreateDomainDataSourceResponseData data = response.getData();
        if(null == data) {
        	return null;
        }
		String datasourceId = data.getDatasourceId();
		logger.info("datasourceId:{}", datasourceId);
		return datasourceId;
	}

	@Override
	public KusciaDataSourceInfo queryDataSource(GrpcApiInfo apiInfo, String domainId, String dataSourceId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		Domaindatasource.QueryDomainDataSourceRequest request = Domaindatasource.QueryDomainDataSourceRequest.newBuilder()
                .setDatasourceId(dataSourceId)
                .setDomainId(domainId)
                .build();
		QueryDomainDataSourceResponse response = new KusciaDomainDataSourceRpcImpl(apiProperties).queryDomainDataSource(request);
		DomainDataSource data = response.getData();
		logger.info("DataSourceResponse:{}", data);
		return KusciaDataSourceInfo.builder()
				.domainId(data.getDomainId())
				.datasourceId(data.getDatasourceId())
				.name(data.getName())
				.type(data.getType())
				.status(data.getStatus())
				.infoKey(data.getInfoKey())
				.accessDirectly(data.getAccessDirectly())
				.build();
	}

	@Override
	public void removeDataSource(GrpcApiInfo apiInfo, String domainId, String dataSourceId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		Domaindatasource.DeleteDomainDataSourceRequest request = Domaindatasource.DeleteDomainDataSourceRequest.newBuilder()
                .setDatasourceId(dataSourceId)
                .setDomainId(domainId)
                .build();
		DeleteDomainDataSourceResponse response = new KusciaDomainDataSourceRpcImpl(apiProperties).deleteDomainDataSource(request);
		org.secretflow.v1alpha1.common.Common.Status status = response.getStatus();
		logger.info("{}", status);
	}

	@Override
	public List<KusciaDataSourceInfo> queryDataSources(GrpcApiInfo apiInfo, String domainId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		ListDomainDataSourceRequest request = ListDomainDataSourceRequest.newBuilder().setDomainId(domainId).build();
		ListDomainDataSourceResponse response =  new KusciaDomainDataSourceRpcImpl(apiProperties).listDomainDataSource(request);
		if(null == response) {
        	return null;
        }
		 Map<Descriptors.FieldDescriptor,Object> datas = response.getAllFields();
        if(null == datas) {
        	return null;
        }
        for (Map.Entry<Descriptors.FieldDescriptor,Object> map : datas.entrySet()) {
        	logger.info("{}", map.getKey());
        	logger.info("{}", map.getValue());
		}
		return null;
	}

}
